#pragma once

#include <sys/sys_thread.h>
#include <interface/aot_inet_interface.h>
#include <interface/aot_inet_interface2.h>
#include <interface/aot_im_interface.h>
#include <map>
#include "aot_inet_syn_client.h"

class sm_base;
class im_packet_impl;
class aot_inet_syn_client;
class sm_driver : public xy::thread_svc<xy::MT_SYN_TRAITS, aot::im::iim_packet*>
{
	friend class sm_base;
	friend class aot_inet_syn_client;
	typedef xy::thread_svc<xy::MT_SYN_TRAITS, aot::im::iim_packet*> base_type;
public:
	sm_driver();
	virtual ~sm_driver();
public:
	bool init();
	void stop();
	bool start();
	void set_event_handler(aot::im::iim_event_handler* evh)
	{
		this->evh_ = evh;
	}
	void notify_event(int ev, WPARAM wparam, LPARAM lparam, aot::tt::sys_event_param_t* p = NULL)
	{
		if( this->evh_ )
		{
			this->evh_->on_event(ev, wparam, lparam, p);
		}
	}
	void delete_sm_all();
protected:
	virtual int svc();
private:
	void dispatch(aot::im::iim_packet* pkt);
	sm_base* find_sm_by_iid(int sm_iid);
	sm_base* find_sm_by_call_id(const char* call_id);
	sm_base* create_sm(aot::im::iim_packet* pkt);
	bool insert_sm(sm_base* sm);
	void delete_sm(const char* call_id);
	void delete_sm(sm_base* sm);
public:
	aot::tt::iobj_auto_ptr<aot::inet::itimer_queue_driver> timer_queue_driver_;

	typedef xy::null_mutex mutex_type;
	typedef xy::auto_lock< mutex_type > auto_lock_type;
	mutex_type mutex_;

	typedef std::map<std::string, sm_base*> sm_map_type;
	sm_map_type sm_map_;

	bool is_init_;
	aot_inet_syn_client channel_;
	aot::im::iim_event_handler* evh_;
	std::string glb_register_call_id_;
};
